package org.naxx.security.function.util;

import java.io.FileWriter;
import java.io.Writer;
import java.util.Map;

import org.apache.log4j.Logger;
import org.naxx.security.Main;
import org.naxx.security.datatype.DataType;
import org.naxx.security.datatype.DataTypeResolver;
import org.naxx.security.util.FileSystemUtil;

/**
 * This is used to generate bag function XML files.
 */
public final class BagXmlFileGenerator {

	private static final Logger logger = Logger.getLogger(BagXmlFileGenerator.class);
	
	public static void main(String[] args) throws Exception {
		Map<String, DataType> dataTypes = Main.getRepository().getService(DataTypeResolver.class).getDefinedDataTypes();
		new BagXmlFileGenerator().generate(dataTypes);
	}
	
	public void generate(Map<String, DataType> dataTypes) throws Exception {
		int counter = 901;
		Writer writer = null;
		try {
			writer = new FileWriter("gen-bag-functions.xml");
			writer.write(this.bagHeader);
			for (Map.Entry<String, DataType> dataTypeEntry : dataTypes.entrySet()) {
				if(!dataTypeEntry.getValue().isExtension()) {
					String typeName = dataTypeEntry.getValue().getName();
					logger.info("Generating bag functions for type '" + typeName + "'");
		
					String template = new String(this.first);
					template = template.replace("[counter]", String.valueOf(counter++));
					template = template.replace("[param]", typeName);
					writer.write(template);
				}
			}
			writer.write(this.footer);
		} finally {
			FileSystemUtil.close(writer);
		}
	}
	
	private void setFunctions(String fileName, Map<String, DataType> dataTypes) throws Exception {
		Writer writer = null;
		try {
			writer = new FileWriter(fileName);
			writer.write("");
			for (Map.Entry<String, DataType> dataTypeEntry : dataTypes.entrySet()) {
				if(!dataTypeEntry.getValue().isExtension()) {
					
				}
			}
		} finally {
			FileSystemUtil.close(writer);
		}
	}
	
	// TODO organize this better
	
	private final String bagHeader = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- "
			+ "Function ids in range [901..1000] are reserved to standard and custom bag functions -->\n"
			+ "<Functions xmlns=\"urn:org:naxx:functions\">\n";

	private final String setHeader = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
			+ "<!-- Function ids in range [1001..1100] are reserved to standard and custom"
			+ " set functions -->\n"
			+ "<Functions xmlns=\"urn:org:naxx:functions\">\n";

	private final String footer = "\n</Functions>";
	
	private final String first = "\n<Function Id=\"[counter]\" IsGeneric=\"true\">\n"
			+ "<Uri>urn:oasis:names:tc:xacml:1.0:function:[param]-one-and-only</Uri>\n"
			+ "<Name>[param]-one-and-only</Name>\n"
			+ "<ReturnDataType DataTypeId=\"19\"/>\n"
			+ "<Parameters NumberOfParameters=\"1\">\n"
			+ "<Parameter DataTypeId=\"17\"/>" + "</Parameters>\n"
			+ "</Function>\n\n";
	
	private final String second = "\n<Function Id=\"[counter]\" IsGeneric=\"true\">"
			+ "<Uri>urn:oasis:names:tc:xacml:1.0:function:[param]-bag-size</Uri>"
			+ "<Name>[param]-bag-size</Name>"
			+ "<ReturnDataType DataTypeId=\"3\"/>"
			+ "<Parameters NumberOfParameters=\"1\">"
			+ "	<Parameter DataTypeId=\"17\"/>"
			+ "</Parameters>"
			+ "</Function>\n\n";
	
	private final String third = "\n<Function Id=\"[counter]\" IsGeneric=\"true\">"
			+ "<Uri>urn:oasis:names:tc:xacml:1.0:function:[param]-is-in</Uri>"
			+ "<Name>[param]-is-in</Name>"
			+ "	<ReturnDataType DataTypeId=\"2\"/>"
			+ "<Parameters NumberOfParameters=\"2\">"
			+ "	<Parameter DataTypeId=\"[param]\"/>"
			+ "	<Parameter DataTypeId=\"17\"/>"
			+ "</Parameters>"
			+ "</Function>\n\n";
	
	private final String fourth = "<Function Id=\"[counter]\" IsGeneric=\"true\">"
			+ "<Uri>urn:oasis:names:tc:xacml:1.0:function:[param]-bag</Uri>"
			+ "<Name>[param]-bag</Name>"
			+ "<ReturnDataType DataTypeId=\"17\" IsGeneric=\"true\"/>"
			+ "<Parameters NumberOfParameters=\"0\">"
			+ "	<Parameter DataTypeId=\"19\"/>"
			+ "</Parameters>"
			+ "	</Function>\n\n";
}
